﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml.XPath;

namespace ServBus.ListForm2010.Common.XSNOperator
{
    //Myschema.xsd
    public class XSN_Myschema : XSNFile
    {
        public bool Initial(XSNOperator p_Context)
        {
            TemplateName = "myschema.xsd";
            SaveToLocal = p_Context.G_SaveToLocal;
            SavePath = p_Context.SaveFolder + "\\" + TemplateName;
            bool rStatus = InitialXmlDocument(p_Context.XSNTemplateFolder);
            return rStatus;
        }

        public override void AppendFieldInfoMainDef(XFieldInfo p_FieldInfo)
        {
            //Insert into myFields
            string refPath = "/xsd:schema/xsd:element[@name='mainForm']/xsd:complexType/xsd:sequence";
            string refDef = string.Format("<xsd:element ref=\"tns:{0}\" minOccurs=\"0\" maxOccurs=\"1\" />",
                p_FieldInfo.UniqueName);
            InsertNode(refPath, refDef);

            //Insert element definition
            InsertNode("/xsd:schema", p_FieldInfo.GetMyschemaElementDef());
        }

        public override void AppendFieldInfoSubDef(XListInfo p_XListInfo)
        {
            InitialSubXListInfoDef();
            AppendSubXListInfoDef(p_XListInfo);
            foreach (ContentTypeInfo ctypeInfo in p_XListInfo.ContentTypeInfoList)
            {
                AppendSubContentTypeInfoDef(p_XListInfo, ctypeInfo);
                AppendSubFieldInfoDef(ctypeInfo);
            }
        }

        #region Private Method

        private void InitialSubXListInfoDef()
        {
            string _subFormPath =
                "/xsd:schema/xsd:element[@name='mainForm']/xsd:complexType/xsd:sequence/xsd:element[@ref='tns:SubForms']";
            XPathNavigator subForm = XPathNav.SelectSingleNode(_subFormPath, XmlNSManager);
            if (subForm == null)
            {
                string refPath = "/xsd:schema/xsd:element[@name='mainForm']/xsd:complexType/xsd:sequence";
                string refDef = string.Format("<xsd:element ref=\"tns:SubForms\" minOccurs=\"0\" maxOccurs=\"1\" />");
                InsertNode(refPath, refDef);

                string elementDef =
                    string.Format(
                        "<xsd:element name=\"SubForms\" ><xsd:complexType><xsd:sequence></xsd:sequence></xsd:complexType></xsd:element>");
                InsertNode("/xsd:schema", elementDef);
            }
        }

        private void AppendSubXListInfoDef(XListInfo p_XListInfo)
        {

            string subXListPath =
                string.Format("/xsd:schema/xsd:element[@name=\"{0}\"]", p_XListInfo.UniqueName);
            XPathNavigator subXList = XPathNav.SelectSingleNode(subXListPath, XmlNSManager);
            if (subXList == null)
            {
                string refPath = "/xsd:schema/xsd:element[@name='SubForms']/xsd:complexType/xsd:sequence";
                string refDef = string.Format("<xsd:element ref=\"tns:{0}\" minOccurs=\"0\"/>", p_XListInfo.UniqueName);
                InsertNode(refPath, refDef);
                string elementDef =
                    string.Format(
                        "<xsd:element name=\"{0}\" ><xsd:complexType><xsd:sequence></xsd:sequence>"
                        + "<xsd:attribute name=\"List_ID\" type=\"xsd:string\"/></xsd:complexType></xsd:element>",
                        p_XListInfo.UniqueName);
                InsertNode("/xsd:schema", elementDef);
            }
        }

        private void AppendSubContentTypeInfoDef(XListInfo p_XListInfo, ContentTypeInfo p_CTypeInfo)
        {
            string refPath = string.Format("/xsd:schema/xsd:element[@name='{0}']/xsd:complexType/xsd:sequence",
                p_XListInfo.UniqueName);
            string refDef = string.Format("<xsd:element ref=\"tns:{0}\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>",
                p_CTypeInfo.UniqueName);
            InsertNode(refPath, refDef);

            string elementDef =
                string.Format(
                    "<xsd:element name=\"{0}\"  ma:displayName=\"{1}\" ><xsd:complexType><xsd:sequence></xsd:sequence>"
                    + "<xsd:attribute name=\"ContentType_ID\" type=\"xsd:string\"/><xsd:attribute name=\"Item_ID\" type=\"xsd:string\"/></xsd:complexType></xsd:element>",
                    p_CTypeInfo.UniqueName, p_CTypeInfo.ContentTypeName);
            InsertNode("/xsd:schema", elementDef);
        }

        private void AppendSubFieldInfoDef(ContentTypeInfo p_CTypeInfo)
        {
            foreach (XFieldInfo xFieldInfo in p_CTypeInfo.FieldInfoList)
            {
                //Insert into myFields
                string ctypePath = string.Format("/xsd:schema/xsd:element[@name='{0}']/xsd:complexType/xsd:sequence",
                    p_CTypeInfo.UniqueName);
                string refDef = string.Format("<xsd:element ref=\"tns:{0}\" minOccurs=\"0\" />", xFieldInfo.UniqueName);
                InsertNode(ctypePath, refDef);

                //Insert element definition
                InsertNode("/xsd:schema", xFieldInfo.GetMyschemaElementDef());
            }
        }

        #endregion
    }

    //Sampledata.xml
    public class XSN_Sampledata : XSNFile
    {
        public bool Initial(XSNOperator p_Context)
        {
            TemplateName = "sampledata.xml";
            SaveToLocal = p_Context.G_SaveToLocal;
            SavePath = p_Context.SaveFolder + "\\" + TemplateName;
            bool rStatus = InitialXmlDocument(p_Context.XSNTemplateFolder);
            InitialMainListID(p_Context.MListInfo.ListID.ToString());
            return rStatus;
        }

        private void InitialMainListID(string p_ListID)
        {
            XPathNavigator xNav = XPathNav.SelectSingleNode("/dfs:myFields/dfs:dataFields/tns:mainForm", XmlNSManager);
            if (xNav != null && xNav.MoveToFirstAttribute())
            {
                xNav.SetValue(p_ListID);
            }
        }

        public override void AppendFieldInfoMainDef(XFieldInfo p_FieldInfo)
        {
            InsertDataObjectDef(p_FieldInfo);
            //Insert into myFields
            InsertNode("/dfs:myFields/dfs:dataFields/tns:mainForm", p_FieldInfo.GetTemplateElementDef());
        }

        public override void AppendFieldInfoSubDef(XListInfo p_XListInfo)
        {
            InitialSubXListInfoDef();
            AppendSubXListInfoDef(p_XListInfo);
        }

        #region Private Method

        private void InsertDataObjectDef(XFieldInfo p_FieldInfo)
        {
            if (p_FieldInfo.FieldInfoType.Equals(FieldInfoType.Dropdown) ||
                p_FieldInfo.FieldInfoType.Equals(FieldInfoType.MultiChoice))
            {
                //Insert SampledataOptionDSElement
                string _ODSPath = "/dfs:myFields/xd:DataConnection[@Name='OptionDataSourceConnection']/root";
                InsertNode(_ODSPath, p_FieldInfo.GetSampledataOptionDSElementDef());
            }
            else if (p_FieldInfo.FieldInfoType.Equals(FieldInfoType.LookUp))
            {
                //Insert SampledataDataObject
                InsertNode("/dfs:myFields", p_FieldInfo.GetSampledataDataObjectDef());
            }
        }

        private void InitialSubXListInfoDef()
        {
            if (!CheckNode("/dfs:myFields/dfs:dataFields/tns:mainForm/tns:SubForms"))
            {
                string elementDef = string.Format("<tns:SubForms></tns:SubForms>");
                InsertNode("/dfs:myFields/dfs:dataFields/tns:mainForm", elementDef);
            }
        }

        private void AppendSubXListInfoDef(XListInfo p_XListInfo)
        {
            string listPath = string.Format("/dfs:myFields/dfs:dataFields/tns:mainForm/tns:SubForms/tns:{0}",
                p_XListInfo.UniqueName);
            if (!CheckNode(listPath))
            {
                string elementDef = string.Format("<tns:{0} List_ID=\"{1}\"></tns:{0}>", p_XListInfo.UniqueName,
                    p_XListInfo.ListID);
                InsertNode("/dfs:myFields/dfs:dataFields/tns:mainForm/tns:SubForms", elementDef);
            }

            foreach (ContentTypeInfo ctypeInfo in p_XListInfo.ContentTypeInfoList)
            {
                AppendSubContentTypeInfoDef(p_XListInfo, ctypeInfo);
            }
        }

        private void AppendSubContentTypeInfoDef(XListInfo p_XListInfo, ContentTypeInfo p_CTypeInfo)
        {
            string elementPath = string.Format("/dfs:myFields/dfs:dataFields/tns:mainForm/tns:SubForms/tns:{0}", p_XListInfo.UniqueName);
            string elementDef = string.Format("<tns:{0} ContentType_ID=\"{1}\" Item_ID=\"\"></tns:{0}>",
                p_CTypeInfo.UniqueName, p_CTypeInfo.ContentTypeId);
            InsertNode(elementPath, elementDef);
            foreach (XFieldInfo sFieldInfo in p_CTypeInfo.FieldInfoList)
            {
                AppendSubFieldInfoDef(p_XListInfo, p_CTypeInfo, sFieldInfo);
            }
        }

        private void AppendSubFieldInfoDef(XListInfo p_XListInfo, ContentTypeInfo p_CTypeInfo, XFieldInfo p_FieldInfo)
        {
            InsertDataObjectDef(p_FieldInfo);
            string elementPath = string.Format("/dfs:myFields/dfs:dataFields/tns:mainForm/tns:SubForms/tns:{0}/tns:{1}", p_XListInfo.UniqueName,
                p_CTypeInfo.UniqueName);
            InsertNode(elementPath, p_FieldInfo.GetTemplateElementDef());
        }

        #endregion
    }

    //Template.xml
    public class XSN_Template : XSNFile
    {
        public bool Initial(XSNOperator p_Context)
        {
            TemplateName = "template.xml";
            SaveToLocal = p_Context.G_SaveToLocal;
            SavePath = p_Context.SaveFolder + "\\" + TemplateName;
            bool rStatus = InitialXmlDocument(p_Context.XSNTemplateFolder);
            InitialMainListID(p_Context.MListInfo.ListID.ToString());
            return rStatus;
        }

        private void InitialMainListID(string p_ListID)
        {
            XPathNavigator xNav = XPathNav.SelectSingleNode("/dfs:myFields/dfs:dataFields/tns:mainForm", XmlNSManager);
            if (xNav != null && xNav.MoveToFirstAttribute())
            {
                xNav.SetValue(p_ListID);
            }
        }

        public override void AppendFieldInfoMainDef(XFieldInfo p_FieldInfo)
        {
            //Insert into myFields
            InsertNode("/dfs:myFields/dfs:dataFields/tns:mainForm", p_FieldInfo.GetTemplateElementDef());
        }

        public override void AppendFieldInfoSubDef(XListInfo p_XListInfo)
        {
            InitialSubXListInfoDef();
            AppendSubXListInfoDef(p_XListInfo);
        }

        #region Private Method

        private void InitialSubXListInfoDef()
        {
            if (!CheckNode("/dfs:myFields/dfs:dataFields/tns:mainForm/tns:SubForms"))
            {
                string elementDef = string.Format("<tns:SubForms></tns:SubForms>");
                InsertNode("/dfs:myFields/dfs:dataFields/tns:mainForm", elementDef);
            }
        }

        private void AppendSubXListInfoDef(XListInfo p_XListInfo)
        {
            string listPath = string.Format("/dfs:myFields/dfs:dataFields/tns:mainForm/tns:SubForms/tns:{0}",
                p_XListInfo.UniqueName);
            if (!CheckNode(listPath))
            {
                string elementDef = string.Format("<tns:{0} List_ID=\"{1}\"></tns:{0}>", p_XListInfo.UniqueName,
                    p_XListInfo.ListID);
                InsertNode("/dfs:myFields/dfs:dataFields/tns:mainForm/tns:SubForms", elementDef);
            }

            foreach (ContentTypeInfo ctypeInfo in p_XListInfo.ContentTypeInfoList)
            {
                AppendSubContentTypeInfoDef(p_XListInfo, ctypeInfo);
            }
        }

        private void AppendSubContentTypeInfoDef(XListInfo p_XListInfo, ContentTypeInfo p_CTypeInfo)
        {
            string elementPath = string.Format("/dfs:myFields/dfs:dataFields/tns:mainForm/tns:SubForms/tns:{0}", p_XListInfo.UniqueName);
            string elementDef = string.Format("<tns:{0} ContentType_ID=\"{1}\" Item_ID=\"\"></tns:{0}>",
                p_CTypeInfo.UniqueName, p_CTypeInfo.ContentTypeId);
            InsertNode(elementPath, elementDef);
            foreach (XFieldInfo sFieldInfo in p_CTypeInfo.FieldInfoList)
            {
                AppendSubFieldInfoDef(p_XListInfo, p_CTypeInfo, sFieldInfo);
            }
        }

        private void AppendSubFieldInfoDef(XListInfo p_XListInfo, ContentTypeInfo p_CTypeInfo, XFieldInfo p_FieldInfo)
        {
            string elementPath = string.Format("/dfs:myFields/dfs:dataFields/tns:mainForm/tns:SubForms/tns:{0}/tns:{1}", p_XListInfo.UniqueName,
                p_CTypeInfo.UniqueName);
            InsertNode(elementPath, p_FieldInfo.GetTemplateElementDef());
        }

        #endregion
    }

    //View.xml
    public class XSN_View : XSNFile
    {
        public bool Initial(XSNOperator p_Context)
        {
            TemplateName = "view1.xsl";
            SaveToLocal = p_Context.G_SaveToLocal;
            SavePath = p_Context.SaveFolder + "\\" + TemplateName;
            bool rStatus = InitialXmlDocument(p_Context.XSNTemplateFolder);
            return rStatus;
        }

        public override void AppendFieldInfoMainDef(XFieldInfo p_FieldInfo)
        {
            //"/xsl:stylesheet/xsl:template/html/body/div/table/tbody"
            string _viewPath = "/xsl:stylesheet/xsl:template/html/body/div/table/tbody";
            InsertNode(_viewPath, p_FieldInfo.GetViewElementDef());
        }

        //not ready
        public override void AppendFieldInfoSubDef(XListInfo p_XListInfo)
        {
            string _viewPath = "/xsl:stylesheet/xsl:template/html/body/div/table/tbody";
            foreach (ContentTypeInfo ctypeInfo in p_XListInfo.ContentTypeInfoList)
            {
                StringBuilder def = new StringBuilder();
                string _LookupFormTableHead = "<tr style=\"MIN-HEIGHT: 31px\" class=\"xdTableOffsetRow\">"
                                              + "<td class=\"xdTableOffsetCellLabel\""
                                              +
                                              " style=\"PADDING-BOTTOM: 4px; PADDING-RIGHT: 5px; VERTICAL-ALIGN: top; PADDING-TOP: 4px\">"
                                              + "<h4>"
                                              + "<span class=\"xdlabel\">{0} - {1}</span>"
                                              + "</h4>"
                                              + "</td>"
                                              + "<td class=\"xdTableOffsetCellComponent\""
                                              +
                                              " style=\"PADDING-BOTTOM: 4px; PADDING-LEFT: 5px; VERTICAL-ALIGN: top; PADDING-TOP: 4px\">"
                                              + "<div>"
                                              + "<span class=\"xdlabel\"></span>"
                                              + "</div>"
                                              + "<div>"
                                              + "<span class=\"xdlabel\"></span>"
                                              + "</div>"
                                              + "<div>";
                def.AppendFormat(_LookupFormTableHead, p_XListInfo.ListTitle, ctypeInfo.ContentTypeName);

                #region Get Top Three Field expect ID&ContentType

                int fieldMax = 0;
                List<XFieldInfo> viewFields = new List<XFieldInfo>();
                foreach (XFieldInfo fld in ctypeInfo.FieldInfoList)
                {
                    //控制ID字段只读
                    if (fld.InternalName.Equals("ID") || fld.InternalName.Equals("ContentType"))
                    {
                        continue;
                    }
                    //
                    if (fld.Hidden || fld.FieldInfoType.Equals(FieldInfoType.Calculated))
                    {
                        continue;
                    }

                    //if (fld.FieldInfoType.Equals(FieldInfoType.LookUp))
                    //{
                    //    continue;
                    //}

                    if (fieldMax == 3)
                    {
                        break;
                    }
                    viewFields.Add(fld);
                    fieldMax++;
                }

                #endregion

                def.AppendFormat("<table style=\"BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; WIDTH: 373px;"
                                  +
                                  " BORDER-COLLAPSE: collapse; WORD-WRAP: break-word; BORDER-TOP-STYLE: none; TABLE-LAYOUT: fixed; BORDER-LEFT-STYLE: none\""
                                  + " class=\"xdRepeatingTable msoUcTable\" title=\"\" border=\"1\""
                                  + " xd:CtrlId=\"CTRL48\" xd:widgetIndex=\"0\">");
                //colgroup
                def.AppendFormat("<colgroup>");
                for (int i = 0; i < viewFields.Count; i++)
                {
                    def.AppendFormat("<col></col>");
                }
                def.AppendFormat("</colgroup>");

                def.AppendFormat("<tbody class=\"xdTableHeader\"><tr style=\"MIN-HEIGHT: 19px\">");
                foreach (XFieldInfo fld in viewFields)
                {
                    def.AppendFormat(
                        "<td style=\"TEXT-ALIGN: center; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 5px; PADDING-RIGHT: 5px; BORDER-RIGHT: medium none; PADDING-TOP: 1px\">"
                        + "<div><h5 style=\"FONT-WEIGHT: normal\"><strong>{0}</strong></h5></div></td>", fld.DisplayName);
                }
                def.AppendFormat("</tr></tbody>");

                def.AppendFormat("<tbody xd:xctname=\"RepeatingTable\">");
                def.AppendFormat("<xsl:for-each select=\"/dfs:myFields/dfs:dataFields/tns:mainForm/tns:SubForms/tns:{0}/tns:{1}\"><tr>", p_XListInfo.UniqueName,
                    ctypeInfo.UniqueName);

                foreach (XFieldInfo sFieldInfo in viewFields)
                {
                    def.Append(sFieldInfo.GetViewSubElementDef());
                }

                def.AppendFormat("</tr></xsl:for-each></tbody></table>");
                string LookupFormTableEnd = "<div class=\"optionalPlaceholder\" xd:xmlToEdit=\"{0}_72\" tabIndex=\"0\""
                                            + " xd:action=\"xCollection::insert\" style=\"WIDTH: 373px\">Insert item"
                                            + " </div>"
                                            + " </div>"
                                            + " </td>"
                                            + " </tr>";
                string lkpFieldUniqueName =
                    ServBus.ListForm2010.Common.XSNOperator.FieldHelper.GetUniquefieldName(
                        (p_XListInfo.UniqueName + ctypeInfo.UniqueName).Replace(" ", "_"));
                def.AppendFormat(LookupFormTableEnd, lkpFieldUniqueName);
                InsertNode(_viewPath, def.ToString());
            }
        }
    }

    //Choices.xsd
    public class XSN_Choices_XSD : XSNFile
    {
        public bool Initial(XSNOperator p_Context)
        {
            TemplateName = "choices.xsd";
            SaveToLocal = p_Context.G_SaveToLocal;
            SavePath = p_Context.SaveFolder + "\\" + TemplateName;
            bool rStatus = InitialXmlDocument(p_Context.XSNTemplateFolder);
            return rStatus;
        }

        public override void AppendFieldInfoMainDef(XFieldInfo p_FieldInfo)
        {
            if (!p_FieldInfo.FieldInfoType.Equals(FieldInfoType.Dropdown) &&
                !p_FieldInfo.FieldInfoType.Equals(FieldInfoType.MultiChoice)) return;
            //insert ref
            string refPath = "/xsd:schema/xsd:element[@name='root']/xsd:complexType/xsd:all";
            string refDef = string.Format(
                "<xsd:element ref=\"{0}\" minOccurs=\"0\" maxOccurs=\"1\"></xsd:element>", p_FieldInfo.UniqueName);
            InsertNode(refPath, refDef);

            //insert element
            InsertNode("/xsd:schema", p_FieldInfo.GetChoiceXSDElementDef());
        }

        public override void AppendFieldInfoSubDef(XListInfo p_XListInfo)
        {
            foreach (ContentTypeInfo ctypeInfo in p_XListInfo.ContentTypeInfoList)
            {
                foreach (XFieldInfo xFieldInfo in ctypeInfo.FieldInfoList)
                {
                    AppendFieldInfoMainDef(xFieldInfo);
                }
            }
        }
    }

    //Choices.xml
    public class XSN_Choices_XML : XSNFile
    {
        public bool Initial(XSNOperator p_Context)
        {
            TemplateName = "choices.xml";
            SaveToLocal = p_Context.G_SaveToLocal;
            SavePath = p_Context.SaveFolder + "\\" + TemplateName;
            bool rStatus = InitialXmlDocument(p_Context.XSNTemplateFolder);
            return rStatus;
        }

        public override void AppendFieldInfoMainDef(XFieldInfo p_FieldInfo)
        {
            if (p_FieldInfo.FieldInfoType.Equals(FieldInfoType.Dropdown) ||
                p_FieldInfo.FieldInfoType.Equals(FieldInfoType.MultiChoice))
            {
                //insert root
                InsertNode("/root", p_FieldInfo.GetChoiceXMLElementDef());
            }
        }

        public override void AppendFieldInfoSubDef(XListInfo p_XListInfo)
        {
            foreach (ContentTypeInfo ctypeInfo in p_XListInfo.ContentTypeInfoList)
            {
                foreach (XFieldInfo xFieldInfo in ctypeInfo.FieldInfoList)
                {
                    AppendFieldInfoMainDef(xFieldInfo);
                }
            }
        }
    }

    //Manifest.xsf
    public class XSN_Manifest : XSNFile
    {
        public bool Initial(XSNOperator p_Context)
        {
            TemplateName = "manifest.xsf";
            SaveToLocal = p_Context.G_SaveToLocal;
            SavePath = p_Context.SaveFolder + "\\" + TemplateName;
            bool rStatus = InitialXmlDocument(p_Context.XSNTemplateFolder);
            AppendExtension(p_Context.G_Site_Url, p_Context.G_XSN_Url);
            return rStatus;
        }

        public override void AppendFieldInfoMainDef(XFieldInfo p_FieldInfo)
        {
            //Insert into xmlToEdit
            if (p_FieldInfo.FieldInfoType.Equals(FieldInfoType.Note) ||
                p_FieldInfo.FieldInfoType.Equals(FieldInfoType.MultiChoice) ||
                p_FieldInfo.FieldInfoType.Equals(FieldInfoType.Url))
            {
                string _xmlToEditPath = "/xsf:xDocumentClass/xsf:views/xsf:view/xsf:editing";
                InsertNode(_xmlToEditPath, p_FieldInfo.GetManifestXmlToEditDef());
            }

            if (!p_FieldInfo.FieldInfoType.Equals(FieldInfoType.LookUp)) return;
            //Insert into File
            string _filePath = "/xsf:xDocumentClass/xsf:package/xsf:files";
            InsertNode(_filePath, p_FieldInfo.GetManifestFileDef());
            //Insert into dataobject
            string _dataobjectPath = "/xsf:xDocumentClass/xsf:dataObjects";
            InsertNode(_dataobjectPath, p_FieldInfo.GetManifestDataObjectDef());
        }

        public override void AppendFieldInfoSubDef(XListInfo p_XListInfo)
        {
            foreach (ContentTypeInfo ctypeInfo in p_XListInfo.ContentTypeInfoList)
            {
                foreach (XFieldInfo xFieldInfo in ctypeInfo.FieldInfoList)
                {
                    AppendFieldInfoMainDef(xFieldInfo);
                }
                AppendSubFormEditing(p_XListInfo, ctypeInfo);
                AppendSubFormMenuArea(p_XListInfo, ctypeInfo);
            }
        }

        private void AppendExtension(string p_Site_Url, string p_XSN_Url)
        {
            XPathNavigator _sXNav = XPathNav.SelectSingleNode("/xsf:xDocumentClass", XmlNSManager);
            string extensionDef = "<xsf:extensions>"
                                   + "<xsf:extension name=\"SolutionDefinitionExtensions\">"
                                   + "<xsf2:solutionDefinition runtimeCompatibility=\"client\">"
                                   + "<xsf2:offline openIfQueryFails=\"yes\" cacheQueries=\"yes\" />"
                                   +
                                   "<xsf2:server formLocale=\"zh-CN\" isPreSubmitPostBackEnabled=\"no\" isMobileEnabled=\"no\" />"
                                   + "<xsf2:solutionPropertiesExtension branch=\"contentTypeTemplate\">"
                                   +
                                   "<xsf2:contentTypeTemplate site=\"{0}\" path=\"template.xsn\" name=\"Form_template\""
                                   + " description=\"Fill out this form.\""
                                   + " browserEnable=\"no\" />"
                                   + "</xsf2:solutionPropertiesExtension>"
                                   + "</xsf2:solutionDefinition>"
                                   + "<xsf3:solutionDefinition>"
                                   + "<xsf3:baseUrl relativeUrlBase=\"{1}\" />"
                                   + "</xsf3:solutionDefinition>"
                                   + "</xsf:extension>"
                                   + "</xsf:extensions>";
            extensionDef = string.Format(extensionDef, p_Site_Url, p_XSN_Url);
            if (_sXNav != null) _sXNav.AppendChild(extensionDef);
        }

        private void AppendSubFormEditing(XListInfo p_XListInfo, ContentTypeInfo ctypeInfo)
        {
            StringBuilder xmlNodeStr = new StringBuilder();
            string ctypeUniqueName =
                    ServBus.ListForm2010.Common.XSNOperator.FieldHelper.GetUniquefieldName(
                        (p_XListInfo.UniqueName + ctypeInfo.UniqueName).Replace(" ", "_"));
            xmlNodeStr.AppendFormat(
                "<xsf:xmlToEdit name=\"{2}_72\" item=\"/dfs:myFields/dfs:dataFields/tns:mainForm/tns:SubForms/tns:{0}/tns:{1}\" container=\"/dfs:myFields\">",
                p_XListInfo.UniqueName, ctypeInfo.UniqueName,
                ctypeUniqueName);
            xmlNodeStr.AppendFormat(
                "<xsf:editWith caption=\"{0}\" xd:autogeneration=\"template\" component=\"xCollection\">",
                p_XListInfo.UniqueName);
            xmlNodeStr.AppendFormat(
                "<xsf:fragmentToInsert><xsf:chooseFragment parent=\"dfs:dataFields/tns:mainForm\" innerFragment=\"tns:SubForms/tns:{0}/tns:{1}\" ><tns:SubForms><tns:{0} List_ID=\"{3}\" ><tns:{1} ContentType_ID=\"{2}\" Item_ID=\"\" >",
                p_XListInfo.UniqueName, ctypeInfo.UniqueName, ctypeInfo.ContentTypeId, p_XListInfo.ListID);
            foreach (XFieldInfo sFieldInfo in ctypeInfo.FieldInfoList)
            {
                if (sFieldInfo.DisplayName == "ID")
                {
                    xmlNodeStr.AppendFormat("<tns:{0}>1</tns:{0}>", sFieldInfo.UniqueName);
                }
                else
                {
                    xmlNodeStr.AppendFormat(sFieldInfo.GetTemplateElementDef());
                }
            }
            xmlNodeStr.AppendFormat(
                "</tns:{1}></tns:{0}></tns:SubForms></xsf:chooseFragment></xsf:fragmentToInsert></xsf:editWith></xsf:xmlToEdit>",
                p_XListInfo.UniqueName, ctypeInfo.UniqueName);
            InsertNode("/xsf:xDocumentClass/xsf:views/xsf:view/xsf:editing", xmlNodeStr.ToString());
        }

        private void AppendSubFormMenuArea(XListInfo p_XListInfo, ContentTypeInfo ctypeInfo)
        {
            string edirAreaStr = "<xsf:button action=\"xCollection::insertBefore\" xmlToEdit=\"{0}_72\""
                                 + " caption=\"Insert {1} before\" showIf=\"immediate\"/>"
                                 + "<xsf:button action=\"xCollection::insertAfter\" xmlToEdit=\"{0}_72\""
                                 + " caption=\"Insert {1} after\" showIf=\"immediate\"/>"
                                 + "<xsf:button action=\"xCollection::remove\" xmlToEdit=\"{0}_72\""
                                 + " caption=\"Remove {1}\" showIf=\"immediate\"/>"
                                 + "<xsf:button action=\"xCollection::insert\" xmlToEdit=\"{0}_72\""
                                 + " caption=\"Insert {1}\" showIf=\"immediate\"/>";
            string ctypeUniqueName =
                    ServBus.ListForm2010.Common.XSNOperator.FieldHelper.GetUniquefieldName(
                        (p_XListInfo.UniqueName + ctypeInfo.UniqueName).Replace(" ", "_"));
            edirAreaStr = string.Format(edirAreaStr, ctypeUniqueName,
                ctypeInfo.ContentTypeName);
            InsertNode("/xsf:xDocumentClass/xsf:views/xsf:view/xsf:menuArea", edirAreaStr);
        }
    }

    //builtincontrolsschema.xsd
    public class XSN_Builtincontrolsschema : XSNFile
    {
        public bool Initial(XSNOperator p_Context)
        {
            TemplateName = "builtincontrolsschema.xsd";
            SaveToLocal = p_Context.G_SaveToLocal;
            SavePath = p_Context.SaveFolder + "\\" + TemplateName;
            bool rStatus = InitialXmlDocument(p_Context.XSNTemplateFolder);
            return rStatus;
        }
    }

    //rootschema.xsd
    public class XSN_Rootschema : XSNFile
    {
        public bool Initial(XSNOperator p_Context)
        {
            TemplateName = "rootschema.xsd";
            SaveToLocal = p_Context.G_SaveToLocal;
            SavePath = p_Context.SaveFolder + "\\" + TemplateName;
            bool rStatus = InitialXmlDocument(p_Context.XSNTemplateFolder);
            return rStatus;
        }
    }

    //Lookup.xsd
    public class XSN_Lookup : XSNFile
    {
        public bool Initial(XSNOperator p_Context)
        {
            TemplateName = "lookup.xsd";
            SaveToLocal = p_Context.G_SaveToLocal;
            SavePath = p_Context.SaveFolder + "\\" + TemplateName;
            bool rStatus = InitialXmlDocument(p_Context.XSNTemplateFolder);
            return rStatus;
        }

        public override void AppendFieldInfoMainDef(XFieldInfo p_FieldInfo)
        {
        }

        public override void AppendFieldInfoSubDef(XListInfo p_XListInfo)
        {
        }
    }

    //package.ddf
    public class XSN_DDF
    {
        private string TemplateName { get; set; }

        public string SavePath { get; private set; }

        public bool SaveToLocal
        {
            get { return _saveToLocal; }
            set { _saveToLocal = value; }
        }

        private bool _saveToLocal;

        public void Initial(XSNOperator p_Context)
        {
            try
            {
                TemplateName = "package.ddf";
                SaveToLocal = p_Context.G_SaveToLocal;
                SavePath = p_Context.SaveFolder + "\\" + TemplateName;

                File.Copy(p_Context.XSNTemplateFolder + TemplateName, SavePath, true);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
    }
}